import scala.collection.mutable

object ScoreSystem {
  // 定义科目列表
  val subjects = List("数学", "语文", "英语", "物理", "化学")

  // 学生数据结构：(学号, 姓名, 班级, 五门科目成绩)
  type Student = (String, String, Int, List[Int])

  def main(args: Array[String]): Unit = {
    // 生成测试数据（4个班级，每个班级30名学生）
    val students = generateTestData()

    // 1. 计算每个学生的总分和平均分
    val studentsWithStats = calculateStudentStats(students)

    // 2. 按班级统计各分数段人数
    val scoreRangeStats = calculateScoreRanges(studentsWithStats)

    // 3. 筛选优秀学生（所有科目及格且平均分≥85）
    val excellentStudents = filterExcellentStudents(studentsWithStats)

    // 4. 生成每个班级的各科平均分排名
    val classSubjectAvg = calculateClassSubjectAvg(students)
    val subjectRankings = rankSubjectsByClass(classSubjectAvg)

    // 5. 输出年级总分排名前10的学生
    val top10Students = rankTop10Students(studentsWithStats)

    // 生成报告
    generateReports(studentsWithStats, scoreRangeStats, excellentStudents,
      subjectRankings, top10Students)
  }

  // 生成测试数据
  def generateTestData(): List[Student] = {
    val random = new scala.util.Random(42) // 固定种子，保证结果可复现
    (for {
      classNum <- 1 to 4
      studentId <- 1 to 30
    } yield {
      val scores = List.fill(5)(random.nextInt(41) + 60) // 60-100分
      // 使用格式化字符串生成学号（如1班1号为"101"，4班30号为"430"）
      (f"$classNum${studentId}%02d",
        s"学生${classNum}-${studentId}",
        classNum,
        scores)
    }).toList
  }

  // 计算每个学生的总分和平均分
  def calculateStudentStats(students: List[Student]): List[(Student, Int, Double)] = {
    for (student <- students) yield {
      val (id, name, cls, scores) = student
      val total = scores.sum
      val avg = total.toDouble / scores.length
      (student, total, avg)
    }
  }

  // 按班级统计各分数段人数
  def calculateScoreRanges(students: List[(Student, Int, Double)]):
  Map[Int, Map[String, Int]] = {

    val result = mutable.Map[Int, mutable.Map[String, Int]]()

    // 初始化每个班级的分数段统计
    for (cls <- 1 to 4) {
      result(cls) = mutable.Map("90+" -> 0, "80-89" -> 0, "70-79" -> 0, "60-69" -> 0, "<60" -> 0)
    }

    // 统计每个学生的总分所在分数段
    for ((student, total, _) <- students) {
      val (_, _, cls, _) = student
      val range = total match {
        case t if t >= 450 => "90+"   // 5科总分90+即450+
        case t if t >= 400 => "80-89" // 400-449
        case t if t >= 350 => "70-79" // 350-399
        case t if t >= 300 => "60-69" // 300-349
        case _ => "<60"
      }
      result(cls)(range) += 1
    }

    // 转换为不可变Map
    result.map { case (k, v) => (k, v.toMap) }.toMap
  }

  // 筛选优秀学生
  def filterExcellentStudents(students: List[(Student, Int, Double)]): List[(Student, Int, Double)] = {
    for {
      (student, total, avg) <- students
      val (_, _, _, scores) = student
      if avg >= 85 && scores.forall(_ >= 60) // 所有科目及格且平均分≥85
    } yield (student, total, avg)
  }

  // 计算每个班级的各科平均分
  def calculateClassSubjectAvg(students: List[Student]): Map[Int, List[Double]] = {
    val classScores = mutable.Map[Int, List[List[Int]]]().withDefaultValue(Nil)

    // 按班级收集各科成绩
    for (student <- students) {
      val (_, _, cls, scores) = student
      classScores(cls) = scores :: classScores(cls)
    }

    // 计算每个班级的各科平均分
    (for {
      cls <- 1 to 4
    } yield {
      val scoresPerSubject = classScores(cls).transpose
      val avgPerSubject = scoresPerSubject.map(_.sum.toDouble / 30)
      (cls, avgPerSubject)
    }).toMap
  }

  // 按班级对科目进行排名
  def rankSubjectsByClass(classSubjectAvg: Map[Int, List[Double]]): Map[Int, List[(String, Double, Int)]] = {
    (for {
      (cls, avgScores) <- classSubjectAvg
    } yield {
      // 关联科目名称和平均分
      val subjectWithAvg = subjects.zip(avgScores)
      // 按平均分降序排序并添加排名
      val ranked = subjectWithAvg.sortBy(-_._2).zipWithIndex.map {
        case ((subj, avg), idx) => (subj, avg, idx + 1)
      }
      (cls, ranked)
    }).toMap
  }

  // 排名前10的学生
  def rankTop10Students(students: List[(Student, Int, Double)]): List[(Student, Int, Double, Int)] = {
    // 按总分降序排序
    val sorted = students.sortBy(-_._2)
    // 取前10并添加排名
    sorted.take(10).zipWithIndex.map { case (student, idx) =>
      (student._1, student._2, student._3, idx + 1)
    }
  }

  // 生成所有报告
  def generateReports(studentsWithStats: List[(Student, Int, Double)],
                      scoreRangeStats: Map[Int, Map[String, Int]],
                      excellentStudents: List[(Student, Int, Double)],
                      subjectRankings: Map[Int, List[(String, Double, Int)]],
                      top10Students: List[(Student, Int, Double, Int)]): Unit = {

    // 1. 班级分数段统计报告
    println("=" * 50)
    println("班级分数段统计报告")
    println("-" * 50)
    for (cls <- 1 to 4) {
      println(s"班级 $cls:")
      val ranges = scoreRangeStats(cls)
      for ((range, count) <- ranges) {
        println(f"  $range: $count 人 (${count.toDouble/30*100}%.1f%%)")
      }
      println()
    }

    // 2. 优秀学生名单
    println("=" * 50)
    println(s"优秀学生名单 (共 ${excellentStudents.size} 人)")
    println("-" * 50)
    excellentStudents.foreach { case ((id, name, cls, _), total, avg) =>
      println(f"$id  $name (班级 $cls): 总分 $total, 平均分 $avg%.1f")
    }
    println()

    // 3. 班级各科平均分排名
    println("=" * 50)
    println("班级各科平均分排名")
    println("-" * 50)
    for (cls <- 1 to 4) {
      println(s"班级 $cls:")
      val rankings = subjectRankings(cls)
      rankings.foreach { case (subj, avg, rank) =>
        println(f"  第 $rank 名: $subj - $avg%.1f 分")
      }
      println()
    }

    // 4. 年级总分排名前10
    println("=" * 50)
    println("年级总分排名前10学生")
    println("-" * 50)
    top10Students.foreach { case ((id, name, cls, _), total, avg, rank) =>
      println(f"第 $rank 名: $id $name (班级 $cls) - 总分 $total, 平均分 $avg%.1f")
    }
    println("=" * 50)
  }
}
